from django.contrib import auth
from django.contrib.auth import authenticate
from django.contrib.auth.hashers import check_password
from django.core.mail import EmailMessage,send_mail
from django.urls import reverse

from users.models import User
from django.forms import model_to_dict
from django.http import JsonResponse,HttpResponse
from django.shortcuts import render, redirect
from django_redis import get_redis_connection

from datetime import datetime
from hashlib import md5

def register2(request):
    if request.method == 'GET':
        return render(request,'register.html')
    else:
        username = request.POST.get('username')
        password = request.POST.get('password')
        email = request.POST.get('email')
        phone = request.POST.get('phone')
        avatar = request.FILES.get('avatar')
        if User.objects.filter(username=username).exists():
            return JsonResponse({'code':400,'msg':'用户名已注册'},safe=True)
        user = User.objects.create_user(username=username,password=password,email=email,phone=phone,avatar=avatar)
        if user:
            return JsonResponse({'code':200,'msg':'注册成功'},safe=True)
        return JsonResponse({'code': 400, 'msg': '注册失败'}, safe=True)

def login2(request):
    next=request.GET.get('next')
    if request.method =='GET':
        return render(request, 'login.html', {'next':next})
    else:
        username = request.POST.get('username')
        password = request.POST.get('password')
        if User.objects.filter(username=username).exists()==False:
            return render(request, 'login.html', {'err': '用户名不存在'})
        # user =User.objects.get(username=username,password=md5(password))
        # request.session['user']=username
        #验证用户名密码是否正确
        user=authenticate(username=username,password=password)
        if user:
            #将登录信息存入session
            auth.login(request,user)
            #设置session过期时间
            request.session.set_expiry(0) #随浏览器关闭过期
            if next:
                return redirect(next)
            return redirect('/newsm/news')
        return render(request, 'login.html', {'err': '用户名或密码错误'})

'''
  cookie:只能存储键值对，在客服端与服务端来回传递(银行卡)
  session:会话，登录--》注销
       1）第一次登录,服务端有一个sessionstore，提供一个session对象，用户存储用户登录信息
       并将sessionId存储到cookie
       2）下次访问服务端,服务端根据cookie上的sessionId去sessionstore看是否有对象的session对象
        如果有:说明已登录，
        没有：说明没有登录，跳转到登录页面
       注销:
          session销毁
          session清空 
  session方法:
     set_expiry(val)
        int： 如果是n,n秒后过期，如果是0，随浏览器关闭过期
        datetime: 指定事件过期
        timedetal(): 在未来时间段内过期
     has_key(key)：判断session是是否有某个key
     flush(): 清空session
   
'''
def sendEmail(request, user):
    now = datetime.now()
    msg = f'u={user.pk}&e=utf8&t={now.timestamp()}'
    sign = md5(msg.encode()).hexdigest()  # 生成签名
    url = f'http://localhost:8000/users/active?{msg}&sign={sign}'
    subject = f'【奇酷】-新闻网'
    body = f'''
                <div style="width: 500px; background-color: #efe3e3;border-radius: 10px;padding: 10px 20px;margin: 0 auto; ">
                    <h3>尊敬的{user.username}用户:</h3>
                    <p>您于{now.strftime('%Y-%m-%d %H:%M:%S')} 注册成为了本网站的会员,点击下方链接激活账号</p>
                    <p style="word-break: break-all;"><a href="{url}">{url}</a></p>
                    <p>该链接将会在30分钟后失效、如不是本人操作，忽略该邮件即可!</p>
                    <p>【奇酷内部网官方】</p>
                </div>
                '''
    # 邮件发送
    email = EmailMessage(
        subject=subject,
        body=body,
        from_email='w18738241658@163.com',
        to=[user.email],
    )
    email.content_subtype = "html"  # 如果邮件内容是HTML
    email.send(fail_silently=False)
    # redis存储，设置url过期时间
    with get_redis_connection() as redis_conn:
        key = f'active:{user.pk}'
        # 过期时间30分钟
        redis_conn.set(key, url, 60 * 30)

    return url

def register(request):
    if request.method == 'GET':
        return render(request, 'register.html')
    else:
        username = request.POST.get('username')
        password = request.POST.get('password')
        email = request.POST.get('email')
        phone = request.POST.get('phone')
        avatar = request.FILES.get('avatar')
        if User.objects.filter(username=username).exists():
            return JsonResponse({'code': 400, 'msg': '用户名已注册'}, safe=True)
        user = User.objects.create_user(is_active=False, username=username, email=email, password=password, phone=phone,
                                        avatar=avatar)
        if user:
            # 发送邮件
            url = sendEmail(request, user)
            return JsonResponse({'code': 200, 'msg': '注册成功,去邮箱激活'}, safe=True)
        return JsonResponse({'code': 400, 'msg': '注册失败'}, safe=True)

def active(request):
    u = request.GET.get('u')
    e = request.GET.get('e')
    t = request.GET.get('t')
    old_sign = request.GET.get('sign')  #传过来的签名
    msg = f'u={u}&e={e}&t={t}'
    new_sign = md5(msg.encode()).hexdigest()  # 生成新的签名
    if old_sign == new_sign:
        # redis存储，设置url过期时间
        with get_redis_connection() as redis_conn:
            key = f'active:{u}'
            if redis_conn.exists(key):  # 判断key是否存在
                # 激活
                rows = User.objects.filter(id=int(u)).update(is_active=True)
                if rows:
                    redis_conn.delete(key)  # 激活成功，删除key
                    return HttpResponse("<h1>激活成功,去<a href='/users/login'>登录</a></h1>")
                return HttpResponse("<h1>激活失败，去邮箱重新激活</h1>")
            return HttpResponse("<h1>激活链接已失效</h1>")
    return HttpResponse("<h1>激活失败，请勿篡改数据</h1>")

def login(request):
    next = request.GET.get('next')  # /newsm/news/
    if request.method == 'GET':
        return render(request, 'login.html', {'next': next})
    else:
        username = request.POST.get('username')
        password = request.POST.get('password')
        # 检测用户名是否存在
        queryset=User.objects.filter(username=username)
        if queryset.exists() == False:
            return render(request, 'login.html', {'err': '用户名不存在'})
        user=queryset.first()
        # 检测密码是否正确
        if not check_password(password,user.password):
            return render(request, 'login.html', {'err': '用户名或密码错误'})

        # 检测是否激活
        if not user.is_active:
            # 提示用户激活
            with get_redis_connection() as redis_conn:
                key = f'active:{user.pk}'
                if not redis_conn.exists(key):  # 过期，重新发送邮件
                    sendEmail(request,user)
                return render(request, 'login.html', {'err': '用户未激活，前往邮箱激活'})
        # 将登录信息存入session
        auth.login(request, user)
        # 设置session过期时间
        request.session.set_expiry(0)  # 随浏览器关闭过期
        if next:
            return redirect(next)  # 返回刚才进入登录的页面
        return redirect('/newsm/news')


def logout(request):
    # request.session.flush()
    auth.logout(request)
    # return redirect('/users/login')
    # 解除url硬编码
    return redirect(reverse('users:login'))



















